﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    // Implementiert das IObserver Interface, um Player zu beobachten. Implementierte Methode des Interface ist update();

    public class Pathwalker : iPathwalker, IObserver
    {

       

        public List<String> command = new List<String>();
        Connector connector;
        private Backend backend;
        
        private int currentX;
        private int currentY;
        private bool allowedToWalk = false;


        // Laufrichtungen
        private const String up = "ask:mv:up";
        private const String dwn = "ask:mv:dwn";
        private const String rgt = "ask:mv:rgt";
        private const String lft = "ask:mv:lft";
 


 // -----------------------------------------------------------Konstruktor------------------------------------------------------------

        public Pathwalker(Connector c,Backend b)
        {
            connector = c;
            backend = b;
        }

// ------------------------------------------------------------- Observermethoden ---------------------------------------------------------
        public void update()
        {
            if (backend.myPlayer.X != currentX || backend.myPlayer.Y != currentY)
            {
                Console.WriteLine(currentX + "" + currentY);
                allowedToWalk = true;
            } 
            
        }


//--------------------------------------------------------------- sonstige Methoden -----------------------------------------------------------

        public void stop()
        {
            command.Clear();
        }

        public void nextStep()
        {
            if (command.FirstOrDefault() != null)
            {
              
                

                    switch (command.FirstOrDefault()){

                        case up: 
                            moveUp();
                            break;
                        case dwn:
                            moveDwn();
                            break;
                        case rgt:
                            moveRgt();
                            break;
                        case lft:
                            moveLft();
                            break;
                        default: return;

                    }

                    command.RemoveAt(0);
                
            }

        }

        // Wird von der Gui aufgerufen, wenn KeyEvents W A S D ausgelöst werden.
        public void moveUp()
        {
            Console.WriteLine(allowedToWalk);
            if (allowedToWalk)
            {
                currentX = backend.myPlayer.X;
                currentY = backend.myPlayer.Y;
                connector.send.sendMessage(up);
                allowedToWalk = false;
            }

            // Falls ich nicht nach oben laufen kann wegen Hindernis. Dann ändert sich meine Posi nicht und ich 
            // könnte mich ohne diese Abfrage nicht mehr bewegen.
            if (!backend.GetMap().getCells()[backend.myPlayer.X][backend.myPlayer.Y - 1].IsWalkable)
            {
                allowedToWalk = true;
            }
        }
        public void moveRgt()
        {
            Console.WriteLine(allowedToWalk);

            if (allowedToWalk)
            {
                currentX = backend.myPlayer.X;
                currentY = backend.myPlayer.Y;
                connector.send.sendMessage(rgt);
                allowedToWalk = false;
            }
            if (!backend.GetMap().getCells()[backend.myPlayer.X + 1][backend.myPlayer.Y].IsWalkable)
            {
                allowedToWalk = true;
            }
        }

        public void moveDwn()
        {
            Console.WriteLine(allowedToWalk);

            if (allowedToWalk)
            {
                currentX = backend.myPlayer.X;
                currentY = backend.myPlayer.Y;
                connector.send.sendMessage(dwn);
                allowedToWalk = false;
            }
            if (!backend.GetMap().getCells()[backend.myPlayer.X][backend.myPlayer.Y + 1].IsWalkable)
            {
                allowedToWalk = true;
            }
        }

        public void moveLft()
        {
            Console.WriteLine(allowedToWalk);

            if (allowedToWalk)
            {
                currentX = backend.myPlayer.X;
                currentY = backend.myPlayer.Y;
                connector.send.sendMessage(lft);
                allowedToWalk = false;
            }
            if (!backend.GetMap().getCells()[backend.myPlayer.X - 1][backend.myPlayer.Y].IsWalkable)
            {
                allowedToWalk = true;
            }
        }


        public void setCoords(MapCell startCell,List<MapCell> coordinate)
        {

            MapCell oldCell = startCell;
            

            while (coordinate.FirstOrDefault() != null)
            {
                MapCell currentCell = coordinate.FirstOrDefault();
                coordinate.RemoveAt(0);

                String s = null;
                //nach oben 
                if ((currentCell.X == oldCell.X) && ((currentCell.Y+1) == oldCell.Y))   
                {
                    s = up;       
                }
                //nach unten 
                else if ((currentCell.X == oldCell.X) && ((currentCell.Y - 1) == oldCell.Y))
                {
                    s = dwn;
                }
                //nach links 
                else if (((currentCell.X+1) == oldCell.X) && (currentCell.Y == oldCell.Y))
                {
                    s = lft;                  
                }
                //nach rechts 
                else if (((currentCell.X - 1) == oldCell.X) && (currentCell.Y == oldCell.Y))
                {
                    s = rgt;                
                }
                command.Add(s);
                oldCell = currentCell;

            }


        }

        public int CurrentX
        {
            get
            {
                return this.currentX;
            }
            set
            {
                this.currentX = value;
            }
        }

        public int CurrentY
        {
            get
            {
                return this.currentY;
            }
            set
            {
                this.currentY = value;
            }
        }

        public bool AllowedToWalk
        {
            get
            {
                return this.allowedToWalk;
            }
            set
            {
                this.allowedToWalk = value;
            }
        }

       
    }
}
